package handler

import (
	"fmt"
	"strconv"
	"time"

	"project-info/src/handle/response"
	"project-info/src/model"
	"gorm.io/gorm"

	"project-info/src/lib")

// StandardResponse 标准响应结构
type StandardResponse struct {
	Code      int         `json:"code"`
	Message   string      `json:"message"`
	Data      interface{} `json:"data,omitempty"`
	Timestamp time.Time   `json:"timestamp"`
}

// TokenListResponse 令牌列表响应
type TokenListResponse struct {
	Total int         `json:"total"`
	Page  int         `json:"page"`
	Size  int         `json:"size"`
	Items []TokenInfo `json:"items"`
}

// SessionListResponse 会话列表响应
type SessionListResponse struct {
	Total int           `json:"total"`
	Page  int           `json:"page"`
	Size  int           `json:"size"`
	Items []SessionInfo `json:"items"`
}

// TokenInfo 令牌信息结构
type TokenInfo struct {
	ID         uint      `json:"id"`
	TokenId    string    `json:"tokenId"`
	ClientId   string    `json:"clientId"`
	UserId     uint      `json:"userId"`
	Username   string    `json:"username"`
	Scopes     []string  `json:"scopes"`
	TokenType  string    `json:"tokenType"`
	ExpiresAt  time.Time `json:"expiresAt"`
	Status     string    `json:"status"`
	CreateTime time.Time `json:"createTime"`
}

// SessionInfo 会话信息结构
type SessionInfo struct {
	ID             uint                   `json:"id"`
	SessionId      string                 `json:"sessionId"`
	UserId         uint                   `json:"userId"`
	Username       string                 `json:"username"`
	ClientSessions map[string]interface{} `json:"clientSessions"`
	LoginTime      time.Time              `json:"loginTime"`
	LastActivity   time.Time              `json:"lastActivity"`
	ExpiresAt      time.Time              `json:"expiresAt"`
	IpAddress      string                 `json:"ipAddress"`
	UserAgent      string                 `json:"userAgent"`
	Status         int                    `json:"status"`
}

// SystemStats 系统统计信息
type SystemStats struct {
	Clients struct {
		Total    int `json:"total"`
		Active   int `json:"active"`
		Inactive int `json:"inactive"`
	} `json:"clients"`
	Tokens struct {
		Total   int `json:"total"`
		Active  int `json:"active"`
		Expired int `json:"expired"`
		Revoked int `json:"revoked"`
	} `json:"tokens"`
	Sessions struct {
		Total  int `json:"total"`
		Active int `json:"active"`
		Ended  int `json:"ended"`
	} `json:"sessions"`
	Users struct {
		TotalLogins    int `json:"totalLogins"`
		UniqueUsers    int `json:"uniqueUsers"`
		ActiveSessions int `json:"activeSessions"`
	} `json:"users"`
	RecentActivity struct {
		Last24hLogins      int `json:"last24hLogins"`
		Last24hTokenIssued int `json:"last24hTokenIssued"`
		Last24hErrors      int `json:"last24hErrors"`
	} `json:"recentActivity"`
}

// ListTokens 获取令牌列表
// GET /oidc/admin/tokens
// PaginationParams 通用分页参数
type PaginationParams struct {
	Page   int `json:"page"`
	Size   int `json:"size"`
	Offset int `json:"offset"`
}

// parsePaginationParams 解析分页参数
func parsePaginationParams(c *lib.GinContext) PaginationParams {
	params := PaginationParams{
		Page: 1,
		Size: 10,
	}

	// 解析分页参数
	if pageStr := c.QueryParam("page"); pageStr != "" {
		if p, err := strconv.Atoi(pageStr); err == nil && p > 0 {
			params.Page = p
		}
	}
	if sizeStr := c.QueryParam("size"); sizeStr != "" {
		if s, err := strconv.Atoi(sizeStr); err == nil && s > 0 && s <= 100 {
			params.Size = s
		}
	}
	params.Offset = (params.Page - 1) * params.Size

	return params
}

// TokenQueryParams 令牌查询参数
type TokenQueryParams struct {
	TokenType string
	ClientID  string
	UserID    uint
	Status    string
	PaginationParams
}

// parseTokenQueryParams 解析查询参数
func parseTokenQueryParams(c *lib.GinContext) TokenQueryParams {
	params := TokenQueryParams{
		TokenType:        c.QueryParam("tokenType"),
		ClientID:         c.QueryParam("clientId"),
		Status:           c.QueryParam("status"),
		PaginationParams: parsePaginationParams(c),
	}

	// 解析用户ID
	if userIDStr := c.QueryParam("userId"); userIDStr != "" {
		if uid, err := strconv.ParseUint(userIDStr, 10, 32); err == nil {
			params.UserID = uint(uid)
		}
	}

	return params
}

// applyTokenFilters 应用令牌过滤条件
func applyTokenFilters(query *gorm.DB, params TokenQueryParams, now time.Time) *gorm.DB {
	result := query.Where("deleted = 0")

	if params.ClientID != "" {
		result = result.Where("client_id = ?", params.ClientID)
	}
	if params.UserID > 0 {
		result = result.Where("user_id = ?", params.UserID)
	}
	if params.Status != "" {
		switch params.Status {
		case "active":
			result = result.Where("revoked = 0 AND expires_at > ?", now)
		case "expired":
			result = result.Where("revoked = 0 AND expires_at <= ?", now)
		case "revoked":
			result = result.Where("revoked = 1")
		}
	}

	return result
}

// determineTokenStatus 确定令牌状态
func determineTokenStatus(revoked bool, expiresAt time.Time, now time.Time) string {
	if revoked {
		return "revoked"
	}
	if expiresAt.Before(now) {
		return "expired"
	}
	return "active"
}

func ListTokens(c *lib.GinContext) error {
	params := parseTokenQueryParams(c)
	db := model.DB()
	now := time.Now()
	tokens := make([]TokenInfo, 0)

	var accessCount, refreshCount int64
	// 处理访问令牌
	if params.TokenType == "" || params.TokenType == "access" {
		var accessTokens []model.OIDCAccessToken
		query := applyTokenFilters(db, params, now)
		query.Model(&model.OIDCAccessToken{}).Count(&accessCount)
		query.Model(&model.OIDCAccessToken{}).Limit(params.Size).Offset(params.Offset).Find(&accessTokens)

		for _, token := range accessTokens {
			tokenStatus := determineTokenStatus(token.Revoked, token.ExpiresAt, now)
			tokenInfo := TokenInfo{
				ID:         uint(token.Id),
				TokenId:    fmt.Sprintf("access_%d", token.Id),
				ClientId:   token.ClientID,
				UserId:     uint(token.UserID),
				Username:   token.UserName,
				Scopes:     []string{token.Scope},
				TokenType:  "access",
				ExpiresAt:  token.ExpiresAt,
				Status:     tokenStatus,
				CreateTime: *token.CreateTime,
			}
			tokens = append(tokens, tokenInfo)
		}
	}

	// 处理刷新令牌
	if params.TokenType == "" || params.TokenType == "refresh" {
		var refreshTokens []model.OIDCRefreshToken
		query := applyTokenFilters(db, params, now)
		query.Model(&model.OIDCRefreshToken{}).Count(&refreshCount)
		query.Model(&model.OIDCRefreshToken{}).Limit(params.Size).Offset(params.Offset).Find(&refreshTokens)

		for _, token := range refreshTokens {
			tokenStatus := determineTokenStatus(token.Revoked, token.ExpiresAt, now)
			tokenInfo := TokenInfo{
				ID:         uint(token.Id),
				TokenId:    fmt.Sprintf("refresh_%d", token.Id),
				ClientId:   token.ClientID,
				UserId:     uint(token.UserID),
				Username:   token.UserName,
				Scopes:     []string{token.Scope},
				TokenType:  "refresh",
				ExpiresAt:  token.ExpiresAt,
				Status:     tokenStatus,
				CreateTime: *token.CreateTime,
			}
			tokens = append(tokens, tokenInfo)
		}
	}

	// 获取总数
	totalCount := accessCount + refreshCount

	r := TokenListResponse{
		Total: int(totalCount),
		Page:  params.Page,
		Size:  params.Size,
		Items: tokens,
	}

	return response.JsonOk(c, r, "获取成功")
}

// AuditLog 审计日志结构
type AuditLog struct {
	ID        uint      `json:"id"`
	Action    string    `json:"action"`
	Resource  string    `json:"resource"`
	UserID    uint      `json:"userId"`
	Username  string    `json:"username"`
	IPAddress string    `json:"ipAddress"`
	UserAgent string    `json:"userAgent"`
	Details   string    `json:"details"`
	Timestamp time.Time `json:"timestamp"`
}

// AuditLogListResponse 审计日志列表响应
type AuditLogListResponse struct {
	Total int        `json:"total"`
	Page  int        `json:"page"`
	Size  int        `json:"size"`
	Items []AuditLog `json:"items"`
}

// GetAuditLogs 获取审计日志
// GET /oidc/admin/audit/logs
func GetAuditLogs(c *lib.GinContext) error {
	// 获取分页参数
	pagination := parsePaginationParams(c)

	// 获取其他查询参数
	action := c.QueryParam("action")
	resource := c.QueryParam("resource")
	userIDStr := c.QueryParam("userId")
	startTimeStr := c.QueryParam("startTime")
	endTimeStr := c.QueryParam("endTime")

	// 解析用户ID
	var userID uint
	if userIDStr != "" {
		if uid, err := strconv.ParseUint(userIDStr, 10, 32); err == nil {
			userID = uint(uid)
		}
	}

	// 解析时间范围
	var startTime, endTime time.Time
	if startTimeStr != "" {
		if st, err := time.Parse(time.RFC3339, startTimeStr); err == nil {
			startTime = st
		}
	}
	if endTimeStr != "" {
		if et, err := time.Parse(time.RFC3339, endTimeStr); err == nil {
			endTime = et
		}
	}

	// 由于当前系统可能没有专门的审计日志表，这里模拟返回一些基本的操作日志
	// 实际实现中应该有专门的audit_logs表来记录所有操作
	auditLogs := []AuditLog{}

	// 模拟一些审计日志数据
	// 在实际实现中，这里应该从audit_logs表中查询数据
	if action == "" || action == "token_revoke" {
		auditLogs = append(auditLogs, AuditLog{
			ID:        1,
			Action:    "token_revoke",
			Resource:  "access_token",
			UserID:    1,
			Username:  "admin",
			IPAddress: "127.0.0.1",
			UserAgent: "Mozilla/5.0",
			Details:   "撤销访问令牌",
			Timestamp: time.Now().Add(-1 * time.Hour),
		})
	}

	if action == "" || action == "session_end" {
		auditLogs = append(auditLogs, AuditLog{
			ID:        2,
			Action:    "session_end",
			Resource:  "user_session",
			UserID:    1,
			Username:  "admin",
			IPAddress: "127.0.0.1",
			UserAgent: "Mozilla/5.0",
			Details:   "结束用户会话",
			Timestamp: time.Now().Add(-2 * time.Hour),
		})
	}

	// 应用过滤条件
	filteredLogs := []AuditLog{}
	for _, log := range auditLogs {
		// 过滤条件检查
		if resource != "" && log.Resource != resource {
			continue
		}
		if userID > 0 && log.UserID != userID {
			continue
		}
		if !startTime.IsZero() && log.Timestamp.Before(startTime) {
			continue
		}
		if !endTime.IsZero() && log.Timestamp.After(endTime) {
			continue
		}
		filteredLogs = append(filteredLogs, log)
	}

	// 应用分页
	total := len(filteredLogs)
	start := pagination.Offset
	end := pagination.Offset + pagination.Size
	if start > total {
		start = total
	}
	if end > total {
		end = total
	}

	pagedLogs := []AuditLog{}
	if start < end {
		pagedLogs = filteredLogs[start:end]
	}

	r := AuditLogListResponse{
		Total: total,
		Page:  pagination.Page,
		Size:  pagination.Size,
		Items: pagedLogs,
	}

	return response.JsonOk(c, r, "获取成功")
}

// BatchRevokeTokens 批量撤销令牌
// POST /oidc/admin/tokens/batch-revoke
func BatchRevokeTokens(c *lib.GinContext) error {
	var request struct {
		AccessTokenIds  []uint64 `json:"accessTokenIds"`
		RefreshTokenIds []uint64 `json:"refreshTokenIds"`
		Reason          string   `json:"reason"`
	}

	if err := c.Bind(&request); err != nil {
		return response.JsonFail(c, "请求参数格式错误")
	}

	if len(request.AccessTokenIds) == 0 && len(request.RefreshTokenIds) == 0 {
		return response.JsonFail(c, "令牌ID列表不能为空")
	}

	db := model.DB()
	var revokedCount int64

	if len(request.AccessTokenIds) > 0 {
		// 撤销访问令牌
		result := db.Model(&model.OIDCAccessToken{}).Where("id IN ? AND revoked = 0", request.AccessTokenIds).Update("revoked", 1)
		revokedCount += result.RowsAffected
	}

	if len(request.RefreshTokenIds) > 0 {
		// 撤销刷新令牌
		result := db.Model(&model.OIDCRefreshToken{}).Where("id IN ? AND revoked = 0", request.RefreshTokenIds).Update("revoked", 1)
		revokedCount += result.RowsAffected
	}

	return response.JsonOk(c, map[string]interface{}{
		"revokedCount":   int(revokedCount),
		"requestedCount": len(request.AccessTokenIds) + len(request.RefreshTokenIds),
	}, "批量撤销成功")
}

// BatchEndSessions 批量结束会话
// POST /oidc/admin/sessions/batch-end
func BatchEndSessions(c *lib.GinContext) error {
	var request struct {
		Reason     string   `json:"reason"`
		SessionIds []uint64 `json:"sessionIds"`
	}

	if err := c.Bind(&request); err != nil {
		return response.JsonFail(c, "请求参数格式错误")
	}

	if len(request.SessionIds) == 0 {
		return response.JsonFail(c, "会话ID列表不能为空")
	}

	db := model.DB()
	// 支持通过数字ID或session_id批量结束
	var endedCount int64

	if len(request.SessionIds) > 0 {
		result := db.Model(&model.OIDCUserSession{}).Where("id IN ? AND deleted = 0", request.SessionIds).Update("deleted", 1)
		endedCount += result.RowsAffected
	}

	return response.JsonOk(c, map[string]interface{}{
		"endedCount":     int(endedCount),
		"requestedCount": len(request.SessionIds),
		"reason":         request.Reason,
	}, "批量结束会话成功")
}

// GetToken 获取单个令牌信息
// GET /oidc/admin/tokens/:id
func GetToken(c *lib.GinContext) error {
	tokenID := c.QueryParam("id")
	if tokenID == "" {
		return response.JsonFail(c, "缺少令牌ID参数")
	}

	db := model.DB()
	now := time.Now()
	tokenIDUint, err := strconv.ParseUint(tokenID, 10, 64)
	if err != nil {
		return response.JsonFail(c, "无效的令牌ID格式")
	}

	// 先在访问令牌中查找
	var accessToken model.OIDCAccessToken
	if err := db.Where("id = ? AND deleted = 0", tokenIDUint).First(&accessToken).Error; err == nil {
		// 确定令牌状态
		tokenStatus := "active"
		if accessToken.Revoked {
			tokenStatus = "revoked"
		} else if accessToken.ExpiresAt.Before(now) {
			tokenStatus = "expired"
		}

		tokenInfo := TokenInfo{
			ID:         uint(accessToken.Id),
			TokenId:    fmt.Sprintf("at_%d", accessToken.Id),
			ClientId:   accessToken.ClientID,
			UserId:     uint(accessToken.UserID),
			Username:   fmt.Sprintf("user_%d", accessToken.UserID),
			Scopes:     []string{accessToken.Scope},
			TokenType:  "access",
			ExpiresAt:  accessToken.ExpiresAt,
			Status:     tokenStatus,
			CreateTime: *accessToken.CreateTime,
		}

		return response.JsonOk(c, tokenInfo, "获取成功")
	}

	// 在刷新令牌中查找
	var refreshToken model.OIDCRefreshToken
	if err := db.Where("id = ? AND deleted = 0", tokenIDUint).First(&refreshToken).Error; err == nil {
		// 确定令牌状态
		tokenStatus := "active"
		if refreshToken.Revoked {
			tokenStatus = "revoked"
		} else if refreshToken.ExpiresAt.Before(now) {
			tokenStatus = "expired"
		}

		tokenInfo := TokenInfo{
			ID:         uint(refreshToken.Id),
			TokenId:    fmt.Sprintf("rt_%d", refreshToken.Id),
			ClientId:   refreshToken.ClientID,
			UserId:     uint(refreshToken.UserID),
			Username:   fmt.Sprintf("user_%d", refreshToken.UserID),
			Scopes:     []string{refreshToken.Scope},
			TokenType:  "refresh",
			ExpiresAt:  refreshToken.ExpiresAt,
			Status:     tokenStatus,
			CreateTime: *refreshToken.CreateTime,
		}

		return response.JsonOk(c, tokenInfo, "获取成功")
	}

	return response.JsonFail(c, "令牌不存在")
}

// RevokeToken 撤销令牌
// DELETE /oidc/admin/tokens/:id
func RevokeToken(c *lib.GinContext) error {
	id := c.QueryParam("id")
	tokenType := c.QueryParam("tokenType")

	if id == "" {
		return response.JsonFail(c, "缺少令牌ID参数")
	}

	idUint, err := strconv.ParseUint(id, 10, 64)
	if err != nil {
		return response.JsonFail(c, "无效的令牌ID格式")
	}

	// 使用服务层方法撤销令牌
	if err := oidcService.RevokeTokenByID(idUint, tokenType); err != nil {
		return response.JsonFail(c, "令牌不存在")
	}

	return response.JsonOk(c, nil, "令牌撤销成功")
}

// ListSessions 获取会话列表
// GET /oidc/admin/sessions
func ListSessions(c *lib.GinContext) error {
	// 获取分页参数
	pagination := parsePaginationParams(c)

	// 获取其他查询参数
	userIDStr := c.QueryParam("userId")
	status := c.QueryParam("status") // 1-活跃, 0-已结束
	ipAddress := c.QueryParam("ipAddress")

	// 解析用户ID
	var userID uint
	if userIDStr != "" {
		if uid, err := strconv.ParseUint(userIDStr, 10, 32); err == nil {
			userID = uint(uid)
		}
	}

	sessions := make([]SessionInfo, 0)
	db := model.DB()
	now := time.Now()

	// 获取总数（用于分页信息）
	var totalCount int64
	var oidcSessions []model.OIDCUserSession
	query := db.Model(&model.OIDCUserSession{}).Where("deleted = 0")

	// 应用过滤条件
	if userID > 0 {
		query = query.Where("user_id = ?", userID)
	}
	if status != "" {
		statusInt, _ := strconv.Atoi(status)
		switch statusInt {
		case 1:
			// 活跃会话：未过期
			query = query.Where("expires_at > ?", now)
		case 0:
			// 已结束会话：已过期
			query = query.Where("expires_at <= ?", now)
		}
	}
	if ipAddress != "" {
		query = query.Where("ip_address = ?", ipAddress)
	}
	query.Count(&totalCount)
	query.Limit(pagination.Size).Offset(pagination.Offset).Find(&oidcSessions)

	for _, session := range oidcSessions {
		// 确定会话状态
		sessionStatus := 1 // 活跃
		if session.ExpiresAt.Before(now) {
			sessionStatus = 0 // 已结束
		}

		sessionInfo := SessionInfo{
			ID:             uint(session.Id),
			SessionId:      session.SessionID,
			UserId:         uint(session.UserID),
			Username:       session.UserName,
			ClientSessions: session.ClientSessions,
			LoginTime:      *session.CreateTime,
			LastActivity:   *session.CreateTime,
			ExpiresAt:      session.ExpiresAt,
			IpAddress:      session.IPAddress,
			UserAgent:      session.UserAgent,
			Status:         sessionStatus,
		}

		sessions = append(sessions, sessionInfo)
	}

	r := SessionListResponse{
		Total: int(totalCount),
		Page:  pagination.Page,
		Size:  pagination.Size,
		Items: sessions,
	}

	return response.JsonOk(c, r, "获取成功")
}

// RevokeSession 结束会话
// DELETE /oidc/admin/sessions/:id
func RevokeSession(c *lib.GinContext) error {
	sessionID := c.QueryParam("id")
	if sessionID == "" {
		return response.JsonFail(c, "缺少会话ID参数")
	}

	db := model.DB()
	// 支持通过数字ID或session_id查找
	var session model.OIDCUserSession
	var err error

	// 尝试按数字ID查找
	if sessionIDUint, parseErr := strconv.ParseUint(sessionID, 10, 64); parseErr == nil {
		err = db.Where("id = ? AND deleted = 0", sessionIDUint).First(&session).Error
	}

	// 如果按ID查找失败，尝试按session_id查找
	if err != nil {
		err = db.Where("session_id = ? AND deleted = 0", sessionID).First(&session).Error
	}

	if err != nil {
		return response.JsonFail(c, "会话不存在")
	}

	// 软删除会话
	db.Model(&session).Update("deleted", 1)

	return response.JsonOk(c, nil, "会话结束成功")
}

// GetSystemStats 获取系统统计信息
// GET /oidc/admin/statistics
func GetSystemStats(c *lib.GinContext) error {
	// 使用服务层方法获取基础统计信息
	baseStats, err := oidcService.GetStats()
	if err != nil {
		return response.JsonFail(c, "获取统计信息失败")
	}

	stats := SystemStats{}

	// 从服务层获取的基础统计信息中提取数据
	registeredClients := baseStats["registered_clients"].(int64)
	stats.Clients.Total = int(registeredClients)
	// 由于服务层GetStats方法只返回总数，这里需要额外查询活跃和非活跃客户端
	db := model.DB()
	var activeClients, inactiveClients int64
	db.Model(&model.OIDCClient{}).Where("deleted = 0 AND status = 1").Count(&activeClients)
	db.Model(&model.OIDCClient{}).Where("deleted = 0 AND status = 0").Count(&inactiveClients)
	stats.Clients.Active = int(activeClients)
	stats.Clients.Inactive = int(inactiveClients)

	// 统计令牌信息 - 使用服务层获取的活跃令牌数据，其他数据需要额外查询
	activeTokens := baseStats["active_tokens"].(int64)
	stats.Tokens.Active = int(activeTokens)

	// 其他令牌统计需要额外查询
	now := time.Now()
	var totalAccessTokens, totalRefreshTokens int64
	var expiredAccessTokens, expiredRefreshTokens int64
	var revokedAccessTokens, revokedRefreshTokens int64

	db.Model(&model.OIDCAccessToken{}).Where("deleted = 0").Count(&totalAccessTokens)
	db.Model(&model.OIDCRefreshToken{}).Where("deleted = 0").Count(&totalRefreshTokens)
	db.Model(&model.OIDCAccessToken{}).Where("deleted = 0 AND revoked = 0 AND expires_at <= ?", now).Count(&expiredAccessTokens)
	db.Model(&model.OIDCRefreshToken{}).Where("deleted = 0 AND revoked = 0 AND expires_at <= ?", now).Count(&expiredRefreshTokens)
	db.Model(&model.OIDCAccessToken{}).Where("deleted = 0 AND revoked = 1").Count(&revokedAccessTokens)
	db.Model(&model.OIDCRefreshToken{}).Where("deleted = 0 AND revoked = 1").Count(&revokedRefreshTokens)

	stats.Tokens.Total = int(totalAccessTokens + totalRefreshTokens)
	stats.Tokens.Expired = int(expiredAccessTokens + expiredRefreshTokens)
	stats.Tokens.Revoked = int(revokedAccessTokens + revokedRefreshTokens)

	// 统计会话信息 - 使用服务层获取的活跃会话数据，其他数据需要额外查询
	activeSessions := baseStats["active_sessions"].(int64)
	stats.Sessions.Active = int(activeSessions)

	// 其他会话统计需要额外查询
	var totalSessions, endedSessions int64
	db.Model(&model.OIDCUserSession{}).Where("deleted = 0").Count(&totalSessions)
	db.Model(&model.OIDCUserSession{}).Where("deleted = 0 AND expires_at <= ?", now).Count(&endedSessions)

	stats.Sessions.Total = int(totalSessions)
	stats.Sessions.Ended = int(endedSessions)

	// 统计用户信息 - 活跃会话数据已从服务层获取
	stats.Users.ActiveSessions = int(activeSessions)

	// 其他用户统计需要额外查询
	var totalLogins, uniqueUsers int64
	db.Model(&model.OIDCUserSession{}).Where("deleted = 0").Count(&totalLogins)
	db.Model(&model.OIDCUserSession{}).Where("deleted = 0").Distinct("user_id").Count(&uniqueUsers)

	stats.Users.TotalLogins = int(totalLogins)
	stats.Users.UniqueUsers = int(uniqueUsers)

	// 统计最近24小时活动
	last24Hours := now.Add(-24 * time.Hour)
	var last24hLogins, last24hTokenIssued, last24hErrors int64
	db.Model(&model.OIDCUserSession{}).Where("deleted = 0 AND create_time >= ?", last24Hours).Count(&last24hLogins)
	db.Model(&model.OIDCAccessToken{}).Where("deleted = 0 AND create_time >= ?", last24Hours).Count(&last24hTokenIssued)
	// 错误统计暂时设为0，实际应该有错误日志表
	last24hErrors = 0

	stats.RecentActivity.Last24hLogins = int(last24hLogins)
	stats.RecentActivity.Last24hTokenIssued = int(last24hTokenIssued)
	stats.RecentActivity.Last24hErrors = int(last24hErrors)

	return response.JsonOk(c, stats, "获取成功")
}

// CleanupExpiredTokens 清理过期令牌
// POST /oidc/admin/cleanup
func CleanupExpiredTokens(c *lib.GinContext) error {
	now := time.Now()
	db := model.DB()
	cleanupStats := map[string]int{
		"accessTokens":       0,
		"refreshTokens":      0,
		"authorizationCodes": 0,
		"sessions":           0,
	}

	// 清理过期的访问令牌（软删除）
	result := db.Model(&model.OIDCAccessToken{}).Where("deleted = 0 AND expires_at <= ?", now).Update("deleted", 1)
	cleanupStats["accessTokens"] = int(result.RowsAffected)

	// 清理过期的刷新令牌（软删除）
	result = db.Model(&model.OIDCRefreshToken{}).Where("deleted = 0 AND expires_at <= ?", now).Update("deleted", 1)
	cleanupStats["refreshTokens"] = int(result.RowsAffected)

	// 清理过期的授权码（软删除）
	result = db.Model(&model.OIDCAuthorizationCode{}).Where("deleted = 0 AND expires_at <= ?", now).Update("deleted", 1)
	cleanupStats["authorizationCodes"] = int(result.RowsAffected)

	// 清理过期的会话（软删除）
	result = db.Model(&model.OIDCUserSession{}).Where("deleted = 0 AND expires_at <= ?", now).Update("deleted", 1)
	cleanupStats["sessions"] = int(result.RowsAffected)

	totalCleaned := cleanupStats["accessTokens"] + cleanupStats["refreshTokens"] + cleanupStats["authorizationCodes"] + cleanupStats["sessions"]

	return response.JsonOk(c, map[string]interface{}{
		"totalCleaned": totalCleaned,
		"details":      cleanupStats,
		"cleanupTime":  now,
	}, "清理完成")
}

// OIDCStatus OIDC服务状态
// GET /oidc/status
func OIDCStatus(c *lib.GinContext) error {
	now := time.Now()
	db := model.DB()

	// 计算基本统计信息
	var activeAccessTokens, activeRefreshTokens int64
	db.Model(&model.OIDCAccessToken{}).Where("deleted = 0 AND revoked = 0 AND expires_at > ?", now).Count(&activeAccessTokens)
	db.Model(&model.OIDCRefreshToken{}).Where("deleted = 0 AND revoked = 0 AND expires_at > ?", now).Count(&activeRefreshTokens)
	activeTokens := int(activeAccessTokens + activeRefreshTokens)

	var expiredAccessTokens, expiredRefreshTokens int64
	db.Model(&model.OIDCAccessToken{}).Where("deleted = 0 AND revoked = 0 AND expires_at <= ?", now).Count(&expiredAccessTokens)
	db.Model(&model.OIDCRefreshToken{}).Where("deleted = 0 AND revoked = 0 AND expires_at <= ?", now).Count(&expiredRefreshTokens)
	expiredTokens := int(expiredAccessTokens + expiredRefreshTokens)

	var revokedAccessTokens, revokedRefreshTokens int64
	db.Model(&model.OIDCAccessToken{}).Where("deleted = 0 AND revoked = 1").Count(&revokedAccessTokens)
	db.Model(&model.OIDCRefreshToken{}).Where("deleted = 0 AND revoked = 1").Count(&revokedRefreshTokens)
	revokedTokens := int(revokedAccessTokens + revokedRefreshTokens)

	var activeSessions int64
	db.Model(&model.OIDCUserSession{}).Where("deleted = 0 AND expires_at > ?", now).Count(&activeSessions)

	var totalClients int64
	db.Model(&model.OIDCClient{}).Where("deleted = 0").Count(&totalClients)

	status := map[string]interface{}{
		"service":        "OIDC Provider",
		"version":        "1.0.0",
		"status":         "healthy",
		"timestamp":      now,
		"uptime":         "N/A", // 简化实现
		"clients":        int(totalClients),
		"activeTokens":   activeTokens,
		"expiredTokens":  expiredTokens,
		"revokedTokens":  revokedTokens,
		"activeSessions": int(activeSessions),
		"endpoints": map[string]string{
			"authorization": "/oidc/auth",
			"token":         "/oidc/token",
			"userinfo":      "/oidc/userinfo",
			"jwks":          "/oidc/.well-known/jwks.json",
			"discovery":     "/oidc/.well-known/openid_configuration",
			"revocation":    "/oidc/revoke",
			"introspection": "/oidc/introspect",
			"logout":        "/oidc/logout",
		},
	}

	return response.JsonOk(c, status, "获取成功")
}
